home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Apple II Magazines (PO)
/
Nibble Volume 09, No. 04 (1988-04)(MicroSPARC)(Side A).zip
/
Nibble Volume 09, No. 04 (1988-04)(MicroSPARC)(Side A).po
/
DISK.EJECTOR.S
< prev
next >
Wrap
Text File
|
1996-12-24
|
19KB
|
344 lines
1 ******************************
2 * *
3 * DISK EJECTER FOR APPLE *
4 * 3.5 INCH DISK DRIVES. *
5 * *
6 * Syntax: CALL EJ,S,D *
7 * *
8 * EJ= ADDRESS OF ROUTINE *
9 * S = SLOT # (1-7) *
10 * D = DRIVE # (1-127) *
11 * BOTH MUST BE GIVEN!!!!! *
12 * *
13 * BY Tim Swihart *
14 * *
15 * COPYRIGHT (C) 1987 *
16 * by MicroSPARC, INC. *
17 * Concord, MA 01742 *
18 * *
19 * MERLIN PRO V2.54 *
20 * *
21 ******************************
22 *
23 ORG $8000
24 *
25 CsFF EQU $C0FF ;Address of requested slot
26 * (rewritten during execution)
27 CHKCOM EQU $DEBE ;Checks for comma
28 FRMNUM EQU $DD67 ;Evaluates passed formula
29 GETADR EQU $E752 ;Converts # in FAC to an integer
30 LINNUM EQU $0050 ;Lo-byte of integer from GETADR
31 DRIVE EQU $00FA ;Storage for requested drive #
32 SLOT EQU $00FB ;Stores address for slot #
33 US EQU $00FD ;Stores address for start of
34 * this routine
35 REWRIT EQU $0000 ;This value will be rewritten
36 * during execution
37 USERERR EQU $00FF ;Store error code here when done
38 CMD EQU $00 ;0 = Status, 4 = Control
39 DRV EQU $00 ;Smartport drive #
40 SUBCMD EQU $00 ;3 = Request DIB
41 SIZE EQU $00 ;Number of bytes in CTL
42 TYPE EQU $00 ;Type = $01 for 3.5" disk
43 *
44 * SPECIAL ERROR CODES
45 BADDRIV EQU $CA ;Requested drive NOT a 3.5"
46 BADSLOT EQU $CB ;Requested slot higher than 7
47 BADCARD EQU $CC ;Requested slot not a Smartport
48 *
49 * Any line beginning with the label 'Pxx' (where xx is
50 * a number) MUST be present when you assemble this program.
51 * These labels are used to determine offsets that are
52 * REQUIRED for this program to work properly.
53 *
54 *
55 * First, we buffer off the address where this routine
56 * is currently located and store it at 'US'. If you want
57 * to modify this routine to work from a language other
58 * than APPLESOFT, then you will have to replace the next
59 * four lines of code with a different method for deter-
60 * mining where this routine starts in memory.
61 *
62 START LDA $50 ;Lo-byte of where routine starts
63 STA US ;Buffer it to $00FE
64 LDA $51 ;Hi-byte of where routine starts
65 STA US+1 ;Buffer it to $00FF
66 *
67 *
68 * The starting address is needed so that this routine can
69 * use zero-page indexed addressing to access portions of
70 * itself. Since the last portion of this program is where
71 * the "self-referencing" is taking place, and since this
72 * routine is more than 255 bytes long (the upper limit for
73 * zero-paged indexed addressing is 255), we must adjust
74 * 'US'. This makes sure that all of the upper portion of
75 * this routine can be accessed by means of zero-page
76 * indexed adressing.
77 *
78 CLC
79 LDA US ;Get lo-byte of 'US'
80 ADC #PAS-START ;Add adjustment
81 STA US ;Save new lo-byte of 'US'
82 LDA US+1 ;Get hi-byte of 'US'
83 ADC #$00 ;Adjust hi-byte
84 STA US+1 ;Save new hi-byte of 'US'
85 *
86 *
87 * Now eat the comma that lives between 'EJ' and 'S' in the
88 * user's 'CALL EJ,S,D' command. If you want to use this
89 * routine with an ampersand handler that eats the comma for
90 * you, then either remove the following line or replace it
91 * with three NOP's.
92 *
93 JSR CHKCOM ;'SYNTAX ERROR' if no comma
94 *
95 *
96 * Evaluate the slot passed from the calling program. Make
97 * sure that it is less than 8 (since the highest numbered
98 * slot is slot 7). Returns with a 'SYNTAX ERROR' and puts
99 * a special error code into location $00FF if the slot
100 * number is higher than seven. If there is an syntax error
101 * in the expresion for d location $00FF contain
:
: L 1 0 0 ,
100 * number is higher than seven. If there is an syntax error
101 * in the expresion for 'S', then a 'SYNTAX ERROR' is
102 * returned and location $00FF contains garbage left by
103 * another routine.
104 *
105 JSR FRMNUM ;Evaluate 'S'
106 JSR GETADR ;Convert it to an integer and
107 * store at locations $50 and $51
108 LDA LINNUM ;Get lo-byte from $50
109 CMP #$08 ;Is slot between 0 and 7?
110 BCC CONT ;Yes, so continue
111 LDA #BADSLOT ;No, so prepare special error
112 STA USERERR ;Save it for the user
113 RTS ;Return to calling program
114 CONT ADC #$C0 ;Prepare '$Cs' where 's' is slot
115 STA SLOT+1 ;Store as hi-byte of 'SLOT'
116 LDA #$00 ;Prepare lo-byte of 'SLOT'
117 STA SLOT ;'SLOT' now contains $Cs00
118 *
119 *
120 * Now eat the comma between 'S' and 'D' of the CALL from
121 * the user.
122 *
123 JSR CHKCOM ;'SYNTAX ERROR' if no comma
124 *
125 *
126 * Evaluate the drive number that the user passed to us.
127 * If there is a syntax error in the expression for 'D',
128 * then a 'SYNTAX ERROR' is returned and location $00FF
129 * contains garbage left by some other routine.
130 *
131 JSR FRMNUM ;Evaluate 'D'
132 JSR GETADR ;Convert it to an integer and
133 * store at locations $50 and $51
134 LDA LINNUM ;Get the lo-byte
135 STA DRIVE ;Save it for later
136 *
137 *
138 * Verify that the requested slot contains a Smartport.
139 * If not then return the special error code for 'BADCARD'.
140 *
141 LDY #$01 ;First signature byte is at $Cs01
142 LDA (SLOT),Y ;Get signature byte #1
143 CMP #$20 ;Is it correct?
144 BEQ NEXT1 ;Yes, go check signature byte #2
145 LDA #BADCARD ;No, so prepare special error
146 STA USERERR ;Save it for the user
147 RTS ;Return to calling program
148 NEXT1 LDY #$03 ;Next signature byte is at $Cs03
149 LDA (SLOT),Y ;Get signature byte #2
150 CMP #$00 ;Is it correct?
151 BEQ NEXT2 ;Yes, go check signature byte #3
152 LDA #BADCARD ;No, so prepare special error
153 STA USERERR ;Save it for the user
154 RTS ;Return to calling program
155 NEXT2 LDY #$05 ;Next signature byte is at $Cs05
156 LDA (SLOT),Y ;Get signature byte #3
157 CMP #$03 ;Is it correct?
158 BEQ NEXT3 ;Yes, go check signature byte #4
159 LDA #BADCARD ;No, so prepare special error
160 STA USERERR ;Save it for the user
161 RTS ;Return to calling program
162 NEXT3 LDY #$07 ;Next signature byte is at $Cs07
163 LDA (SLOT),Y ;Get signature byte #4
164 CMP #$00 ;Is it correct?
165 BEQ PAS ;Yes, so continue
166 LDA #BADCARD ;No, so prepare special error
167 STA USERERR ;Save it for the user
168 RTS ;Return to calling program
169 *
170 *
171 * Now that we know we're talking to a Smartport, we need
172 * to set up the command table to talk to the drive so
173 * that we can verify it is a 3.5" drive. To do this, we
174 * need to calculate the Smartport entry point. This is
175 * always three more than the Prodos entry point. The
176 * Prodos entry point is found by adding the value in $CsFF
177 * to $Cs00.
178 *
179 PAS LDY #$FF ;Prepare to get byte at $CsFF
180 LDA (SLOT),Y ;Get value at $CsFF
181 CLC
182 ADC #$03 ;Add three to it
183 STA SLOT ;Save it in lo-byte of 'SLOT'
184 *
185 * Pay attention, things get tricky here. First, we modify
186 * the 'REWRIT' portion of 'JSR REWRIT'. (The accumulator
187 * already holds the lo-byte of the Smartport's entry
188 * point).
189 *
190 LDY #DOIT-PAS+1 ;Offset to middle byte of
191 * 'JSR REWRIT'
192 STA (US),Y ;Put lo-byte of Smartport entry
193 * point into 'JSR REWRIT'
194 LDA SLOT+1 ;Get hi-byte of Smartport entry
195 INY ;Adjust offset
196 STA (US),Y ;Put hi-byte of Smartport entry
197 * point into 'JSR REWRIT'
198 *
199 * Now, modify the address of the command list (CMDLIST).
200 *
201 LDA US ;Get lo-byte of this routine's
202 * starting address
203 LDY #P3-PAS ;Offset to pointer to CMDLIST
204 CLC
205 ADC #CMDLIST-PAS ;Offset to CMDLIST itself
206 STA (US),Y ;CMDLIST pointer's lo-byte
207 LDA US+1 ;Get ready to do hi-byte
208 ADC #$00 ;Hi-byte of CMDLIST's pointer
209 INY ;Adjust the offset
210 STA (US),Y ;CMDLIST pointer's hi-byte
211 *
212 * Now, we modify the address of the control list (CTL).
213 *
214 LDA US ;Get lo-byte of this routine's
215 * starting address
216 LDY #P5-PAS ;Offset to pointer to CTL
217 CLC
218 ADC #CTL-PAS ;Offset to CTL itself
219 STA (US),Y ;Rewrite CTL pointer's lo-byte
220 LDA US+1 ;Get ready to do hi-byte
221 ADC #$00 ;Hi-byte for CTL's pointer
222 INY ;Adjust offset
223 STA (US),Y ;Rewrite CTL pointer's hi-byte
224 *
225 * Now, we modify the address portion of 'JSR DO_IT'.
226 *
227 LDY #P1-PAS+1 ;Offset to middle byte of
228 * 'JSR DO_IT'
229 LDA US ;Get lo-byte of this routine's
230 * starting address
231 CLC
232 ADC #DOIT-PAS ;Offset to 'JSR REWRIT'
233 STA (US),Y ;Rewrite lo-byte of address
234 * portion of 'JSR DO_IT'
235 LDA US+1
236 ADC #$00 ;Prepare hi-byte
237 INY ;Adjust offset for hi-byte
238 STA (US),Y ;Rewrite hi-byte of address
239 * portion of 'JSR DO_IT'
240 *
241 *
242 * Things get a little easier now as we set up the drive #,
243 * command #, subcommand # and the size of the control list
244 * so that we can request the Device Information Block (DIB)
245 * from the drive the user sent.
246 *
247 LDA DRIVE ;Get the drive number
248 LDY #P4-PAS ;Offset to DRV in CMDLIST
249 STA (US),Y ;Rewrite the drive number
250 *
251 LDA #$00 ;CMD = 0 for STATUS call
252 LDY #P2-PAS ;Offset to CMD
253 STA (US),Y ;Rewrite CMD
254 *
255 LDA #$03 ;SUBCMD = 3 to request DIB
256 LDY #P6-PAS ;Offset to SUBCMD
257 STA (US),Y ;Rewrite SUBCMD
258 *
259 *
260 * Now get the DIB from the drive and make sure the drive
261 * is a 3.5" (Unidisk 3.5 or Apple 3.5). If the drive is
262 * NOT a 3.5" drive, then a special error code is placed
263 * in location $00FF and control is returned to the
264 * calling program. If the device does not exist, or some
265 * other error occurs, then that error is placed in
266 * location $00FF and control is returned to the calling
267 * program.
268 *
269 P1 JSR DOIT ;Gets DIB for us
270 BCC WORKED ;If no error then continue
271 STA USERERR ;Else save error
272 RTS ;And go back to calling program
273 WORKED LDY #P7-PAS ;Offset to device type in CTL
274 LDA (US),Y ;Gets TYPE from CTL
275 CMP #$01 ;Is it a 3.5" drive?
276 BEQ MORE ;Yes, so keep going
277 LDA #BADDRIV ;No, so prepare special error
278 STA USERERR ;Save it for the user
279 RTS ;Return to calling program
280 *
281 *
282 * Now, we have to change the command #, subcommand #,
283 * the size of the control list and make sure the first
284 * byte in the control list is zero.
285 *
286 MORE LDA #$04 ;CMD=4 for CONTROL call
287 LDY #P2-PAS ;Offset to CMD
288 STA (US),Y ;Rewrite CMD
289 *
290 * SUBCMD=4 for eject and accumulator already contains 4
291 *
292 LDY #P6-PAS ;Offset to SUBCMD
293 STA (US),Y ;Rewrite SUBCMD
294 *
295 LDA #$00 ;Control list contains zero
296 * bytes for eject command
297 LDY #CTL-PAS ;Offset to SIZE in CTL
298 STA (US),Y ;Rewrite SIZE
299 INY ;Adjust offset
300 STA (US),Y ;Make first byte in CTL equal 0
301 *
302 *
303 * Believe it or not, we're finally ready to eject the
304 * disk!!! Whew, what a ride!!
305 *
306 DOIT JSR REWRIT ;This line kicks the disk out!
307 P2 DB CMD ;0 for STATUS, 4 for CONTROL
308 P3 DA CMDLIST ;Address of the command list
309 * will be rewritten here
310 STA USERERR ;Save any error for the user
311 * A zero will be here if no error
312 RTS ;FINISHED!!!!!!!!
313 *
314 *
315 * Here are the Command List (CMDLIST) and the Control
316 * List (CTL).
317 *
318 CMDLIST DB #$03 ;Number of items in CMDLIST
319 P4 DB DRV ;Drive # requested by user
320 P5 DA CTL ;Address of Control List
321 P6 DB SUBCMD ;Subcommand
322 CTL DB SIZE ;Number of items in CTL if doing
323 * the eject. Device Status Byte
324 * if doing the 'GET DSB'.
325 *
326 * Here are the other 24 bytes in the CTL.
327 *
328 DB $00 ;Size (Lo-byte)
329 DB $00 ;Size (Middle-byte)
330 DB $00 ;Size (Hi-byte)
331 DB $00 ;ID string length
332 DS 16,32 ;ID string (32='SPACE')
333 P7 DB TYPE ;Type byte for device
334 DB $00 ;Subtype for device
335 DW $0000 ;Version (word)
336 *
337 * That's it!
338 *